home *** CD-ROM | disk | FTP | other *** search
- /*
- File: DummySave.c
-
- Copyright 1990 by Thomas Knoll.
-
- Think C source file for DummySave example.
- */
-
- #include <MacTypes.h>
- #include <MemoryMgr.h>
- #include <ResourceMgr.h>
- #include <Quickdraw.h>
- #include <DialogMgr.h>
- #include <OSUtil.h>
- #include <PackageMgr.h>
- #include <StdFilePkg.h>
- #include <SysErr.h>
- #include <ToolboxUtil.h>
- #include <pascal.h>
- #include <SetUpA4.h>
-
- #include "ExportInterface.h"
-
- #define nil 0L
- #define Length(string) (*(unsigned char *)(string))
-
- /* The value of global variables are not preserved between invocations
- of the plug-in, since the plug-in's resource file is closed. To keep
- values around longer, make them part of the following structure. */
-
- typedef struct TPermanent {
- short dummy1; /* None are actually used in this example */
- } TPermanent;
-
- TPermanent gPermanent;
-
- short gResult;
- ExportRecordPtr gStuff;
-
- short gFRefNum;
- short gVRefNum;
-
- /*****************************************************************************/
-
- /* Calls the host's TestAbort function */
-
- Boolean TestAbort (void)
-
- {
- return CallPascalB (gStuff->abortProc);
- }
-
- /*****************************************************************************/
-
- /* Calls the host's UpdateProgress procedure */
-
- void UpdateProgress (done, total)
-
- long done;
- long total;
-
- {
- CallPascal (done, total, gStuff->progressProc);
- }
-
- /*****************************************************************************/
-
- /* Sets the global variables to their default values. */
-
- void InitGlobals (void)
-
- {
- }
-
- /*****************************************************************************/
-
- /* Centers a dialog template 1/3 of the way down on the main screen. */
-
- void CenterDialog (dt)
-
- DialogTHndl dt;
-
- #define menuHeight 20
-
- {
- Rect r;
- short width;
- short height;
-
- width = screenBits.bounds.right;
- height = screenBits.bounds.bottom;
-
- r = (**dt).boundsRect;
- OffsetRect (&r, -r.left, -r.top);
- OffsetRect (&r, (width - r.right) / 2,
- (height - r.bottom - menuHeight) / 3 + menuHeight);
- (**dt).boundsRect = r;
- }
-
- #undef menuHeight
-
- /*****************************************************************************/
-
- /* Displays the about dialog box for the plug-in module. */
-
- void DoAbout (void)
-
- #define dialogID 17000
-
- {
- short item;
- DialogPtr dp;
- DialogTHndl dt;
-
- dt = (DialogTHndl) GetResource ('DLOG', dialogID);
- HNoPurge ((Handle) dt);
- CenterDialog (dt);
-
- dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
-
- ModalDialog (nil, &item);
-
- DisposDialog (dp);
- HPurge ((Handle) dt);
- }
-
- #undef dialogID
-
- /*****************************************************************************/
-
- /* Prepare to export an image. If the plug-in module needs only a limited
- amount of memory, it can lower the value of the 'maxData' field. */
-
- void DoPrepare (void)
-
- {
- if (gStuff->maxData > 0x80000)
- gStuff->maxData = 0x80000;
- }
-
- /*****************************************************************************/
-
- /* Request next block of the image */
-
- void RequestNext (top)
-
- short top;
-
- {
- long count;
-
- /* Compute maximum number of rows we should request at once */
-
- count = gStuff->maxData / gStuff->imageSize.h / gStuff->planes;
-
- if (count < 1) count = 1;
-
- /* Request next block of the image */
-
- gStuff->loPlane = 0;
- gStuff->hiPlane = gStuff->planes - 1;
-
- gStuff->theRect.left = 0;
- gStuff->theRect.right = gStuff->imageSize.h;
- gStuff->theRect.top = top;
-
- if (top + count > gStuff->imageSize.v)
- gStuff->theRect.bottom = gStuff->imageSize.v;
- else
- gStuff->theRect.bottom = top + count;
-
- }
-
- /*****************************************************************************/
-
- /* Verifies that the image mode is supported. Prompts the user for
- a file name to save the image to, and requests the first block of
- of image data. */
-
- void DoStart (void)
-
- #define kStringsID 17000
-
- {
- OSErr err;
- Point where;
- Str255 prompt;
- SFReply reply;
- DialogTHndl dt;
-
- /* This plug-in does not support bitmap images */
-
- if (gStuff->imageMode == exportModeBitmap)
- {
- gResult = exportBadMode;
- return;
- }
-
- /* Get prompt string */
-
- GetIndString (prompt, kStringsID, 1);
-
- /* Center dialog */
-
- dt = (DialogTHndl) GetResource ('DLOG', putDlgID);
- HNoPurge ((Handle) dt);
-
- CenterDialog (dt);
- where.v = (**dt).boundsRect.top;
- where.h = (**dt).boundsRect.left;
-
- HPurge ((Handle) dt);
-
- /* Ask the user */
-
- SFPutFile (where, prompt, gStuff->filename, nil, &reply);
-
- if (!reply.good)
- {
- gResult = 1;
- return;
- }
-
- gVRefNum = reply.vRefNum;
-
- err = FSDelete (reply.fName, gVRefNum);
-
- err = Create (reply.fName, gVRefNum, '????', '????');
-
- if (err != noErr)
- {
- gResult = err;
- return;
- }
-
- err = FSOpen (reply.fName, gVRefNum, &gFRefNum);
-
- if (err != noErr)
- {
- gResult = err;
- return;
- }
-
- /* Request first block of image */
-
- RequestNext (0);
-
- }
-
- #undef kStringsID
-
- /*****************************************************************************/
-
- /* Processes the next chunk of the image. */
-
- void DoContinue (void)
-
- {
- OSErr err;
- short row;
- long count;
-
- for (row = gStuff->theRect.top; row < gStuff->theRect.bottom; row++)
- {
-
- /* See if user was aborted the operation */
-
- if (TestAbort ())
- {
- gResult = 1;
- return;
- }
-
- /* Update the progress indicator */
-
- UpdateProgress ((long) row, (long) gStuff->imageSize.v);
-
- /* Write out this row of the image */
-
- count = gStuff->planes * (long) gStuff->imageSize.h;
-
- err = FSWrite (gFRefNum,
- &count,
- (Ptr) ((long) (gStuff->data) + gStuff->rowBytes *
- (row - gStuff->theRect.top)));
-
- if (err != noErr)
- {
- gResult = err;
- return;
- }
-
- }
-
- /* Request next block of image */
-
- RequestNext (gStuff->theRect.bottom);
-
- }
-
- /*****************************************************************************/
-
- /* This routine will always be called if DoStart does not return an error
- (even if DoContinue returns an error or the user aborts the operation).
- This allows the module to perform any needed cleanup. */
-
- void DoFinish (void)
-
- {
- OSErr err;
-
- /* Close the file */
-
- err = FSClose (gFRefNum);
-
- if (err != noErr)
- {
- gResult = err;
- return;
- }
-
- /* Flush the volume */
-
- err = FlushVol (nil, gVRefNum);
-
- if (err != noErr)
- {
- gResult = err;
- return;
- }
-
- /* Clear the image's unsaved changes flag */
-
- gStuff->dirty = false;
-
- }
-
- /*****************************************************************************/
-
- /* Main dispatching routine. Initializes and sets up the global variables,
- and performs the operation specified by the selector. */
-
- pascal void main (selector, stuff, data, result)
-
- short selector;
- ExportRecordPtr stuff;
- long *data;
- short *result;
-
- {
- Boolean firstTime;
-
- /* Allow access to global variables */
-
- RememberA0 ();
- SetUpA4 ();
-
- /* Copy the current quickdraw globals into the plug-in local copy */
-
- asm
- {
- MOVE.L (A5),A0 ; Get address of real quickdraw globals
- SUB.L #126,A0 ; Move to start
- LEA randSeed,A1 ; Get address of local copy
- MOVE.W #64,D0 ; Globals are 65 words long
- @1 MOVE.W (A0)+,(A1)+ ; Copy a word
- DBF D0,@1 ; Move to next word
- }
-
- /* See if this is the first time called */
-
- if (!*data)
- {
-
- /* Allocate a handle to hold permanent values */
-
- *data = (long) NewHandle (sizeof (TPermanent));
-
- if (!*data)
- {
- *result = memFullErr;
- RestoreA4 ();
- return;
- }
-
- /* Initialize the permanent values */
-
- InitGlobals ();
-
- }
-
- /* Else restore permanent values */
-
- else
- BlockMove (*((Handle) *data), (Ptr) &gPermanent, sizeof (TPermanent));
-
- /* Perform the requested operation */
-
- gStuff = stuff;
- gResult = noErr;
-
- switch (selector)
- {
-
- case exportSelectorAbout:
- DoAbout ();
- break;
-
- case exportSelectorPrepare:
- DoPrepare ();
- break;
-
- case exportSelectorStart:
- DoStart ();
- break;
-
- case exportSelectorContinue:
- DoContinue ();
- break;
-
- case exportSelectorFinish:
- DoFinish ();
- break;
-
- default:
- gResult = exportBadParameters;
-
- }
-
- *result = gResult;
-
- /* Save permanent values */
-
- BlockMove ((Ptr) &gPermanent, *((Handle) *data), sizeof (TPermanent));
-
- /* Restore the application's A4 register */
-
- RestoreA4 ();
-
- }
-